package com.atguigu.webapp.interceptor;

import com.atguigu.common.constant.LoginUser;
import com.atguigu.common.constant.LoginUserContext;
import com.atguigu.common.exception.SelfBusException;
import com.atguigu.common.result.ResultCodeEnum;
import com.atguigu.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class AuthenticationInterceptor implements HandlerInterceptor {


    /**
     * 在请求处理前进行预处理，验证和解析 JWT 令牌。
     *
     * @param request HTTP 请求对象
     * @param response HTTP 响应对象
     * @param handler 请求处理器
     * @return 是否继续处理请求
     * @throws SelfBusException 如果令牌不存在或无效，抛出自定义异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             @NotNull HttpServletResponse response,
                             @NotNull Object handler) {
        // 获取请求头中的 access_token
        String token = request.getHeader("access_token");

        if (token == null) {
            // 如果请求头中没有 access_token，抛出自定义异常
            throw new SelfBusException(ResultCodeEnum.APP_LOGIN_AUTH);
        } else {
            // 解析 JWT 令牌
            Claims claims = JwtUtil.parseToken(token);
            // 获取用户 ID 和用户名
            Long userId = claims.get("userId", Long.class);
            String username = claims.get("username", String.class);
            // 将登录用户信息设置到上下文中
            LoginUserContext.setLoginUser(new LoginUser(userId, username));
        }
        // 继续处理请求
        return true;
    }



    /**
     * 在请求处理完成后清理登录用户信息。
     *
     * @param request HTTP 请求对象
     * @param response HTTP 响应对象
     * @param handler 请求处理器
     * @param ex 处理请求过程中抛出的异常（如果有）
     * @throws Exception 如果发生任何异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        // 清理登录用户信息
        LoginUserContext.clear();
    }
}